package org.liaohailong.library.widget.photoview.guesture;

import android.content.Context;
import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;

import androidx.annotation.NonNull;

/**
 * create by liaohailong
 * time 2023/1/9 14:04
 * desc: 综合手势操作识别逻辑 缩放，平移，旋转
 */
public class VGestureDetector {
    private void log(@NonNull String format, Object... args) {
        String msg = String.format(format, args);
        Log.i("CustomGestureDetector", msg);
    }

    private final RotateGestureDetector rotateGestureDetector;
    private final VScaleGestureDetector scaleGestureDetector;
    private final GestureDetector gestureDetector;

    private Callback callback;

    public VGestureDetector(@NonNull Context context) {
        // 旋转手势
        rotateGestureDetector = new RotateGestureDetector();
        rotateGestureDetector.setCallback((rotateDeg, cx, cy) -> {
            // 旋转回调
            log("onRotate rotateDeg: %s, cx: %s, cy: %s", rotateDeg, cx, cy);
            callback.onRotate((int) rotateDeg, cx, cy);
        });

        // 缩放手势
        scaleGestureDetector = new VScaleGestureDetector();
        scaleGestureDetector.setCallback(new VScaleGestureDetector.Callback() {
            @Override
            public void onScale(float scale, float cx, float cy) {
                if (callback != null) {
                    callback.onScale(scale, cx, cy);
                }
            }
        });

        // 平移 + 单击 + 双击 + 长按
        gestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
            @Override
            public boolean onSingleTapConfirmed(MotionEvent e) {
                log("onSingleTapConfirmed");
                return super.onSingleTapConfirmed(e);
            }

            @Override
            public boolean onSingleTapUp(MotionEvent e) {
                log("onSingleTapUp");
                return super.onSingleTapUp(e);
            }

            @Override
            public boolean onDoubleTap(MotionEvent e) {
                log("onDoubleTap");
                return super.onDoubleTap(e);
            }

            @Override
            public void onLongPress(MotionEvent e) {
                log("onLongPress");
                super.onLongPress(e);
            }

            @Override
            public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
                log("onScroll distanceX: %s, distanceY: %s", distanceX, distanceY);
                if (callback != null) {
                    callback.onScroll(distanceX, distanceY);
                }
                return super.onScroll(e1, e2, distanceX, distanceY);
            }

            @Override
            public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
                log("onFling velocityX: %s, velocityY: %s", velocityX, velocityY);
                return super.onFling(e1, e2, velocityX, velocityY);
            }
        });
    }

    public void setCallback(Callback callback) {
        this.callback = callback;
    }

    public void onTouchEvent(@NonNull MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                log("MotionEvent.ACTION_DOWN");
                if (callback != null) {
                    callback.onActonDown(event);
                }
                break;

            case MotionEvent.ACTION_UP:
            case MotionEvent.ACTION_CANCEL:
                log("MotionEvent.ACTION_UP or MotionEvent.ACTION_CANCEL");
                if (callback != null) {
                    callback.onActionUp(event);
                }
                break;
        }

        rotateGestureDetector.onTouchEvent(event); // 旋转
        scaleGestureDetector.onTouchEvent(event); // 缩放
        gestureDetector.onTouchEvent(event); // 平移 + 单击 + 双击 + 长按

    }


    public interface Callback {
        /**
         * @param event 用户按下，将要开始整个触点事件
         */
        void onActonDown(@NonNull MotionEvent event);

        /**
         * @param dx 根据上次ACTION_MOVE事件的平移量：x轴
         * @param dy 根据上次ACTION_MOVE事件的平移量：y轴
         */
        void onScroll(float dx, float dy);

        /**
         * @param scale 缩放值，每次基于上一次ACTION_MOVE事件计算
         * @param cx    缩放中心点x坐标
         * @param cy    缩放中心点y坐标
         */
        void onScale(float scale, float cx, float cy);

        /**
         * 旋转操作触发回调
         *
         * @param rotateDeg 基于手机屏幕坐标系，每次ACTION_MOVE事件造成的旋转角度
         * @param cx        旋转中心点x坐标，以第一次两指按下时形成的线为基准
         * @param cy        旋转中心点y坐标，以第一次两指按下时形成的线为基准
         */
        void onRotate(int rotateDeg, float cx, float cy);

        /**
         * @param event 用户松手，整个触点事件结束了
         */
        void onActionUp(@NonNull MotionEvent event);
    }
}
